/***************************************************************************
 * Copyright 2012-2013 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the contract ICT-257367.
 *
 * Authors:
 *      Salvatore Piccione (TXT e-solutions SpA)
 *
 * Contributors:
 *        Domenico Rotondi (TXT e-solutions SpA)
 **************************************************************************/
package it.txt.ens.client.core.factory;

import it.txt.ens.client.core.ENSBrokerConnectionParameters;

import java.util.Date;

/**
 * This interface defines a factory to create instances of {@link ENSBrokerConnectionParameters}.
 * 
 * @author Salvatore Piccione (TXT e-solutions SpA - salvatore.piccione AT txtgroup.com)
 * @author Domenico Rotondi (TXT e-solutions SpA - domenico.rotondi AT txtgroup.com)
 *
 */
public interface ENSBrokerConnectionParametersFactory {

    static final String PREFIX = "ens.broker.conn.params.";
    /**
     * The name of the configuration parameter indicating the identifier of the ENS broker user.
     */
    public static final String SUBJECT_ID = PREFIX + "subjectID";
    /**
     * The name of the configuration parameter indicating the access token to be used when connecting to the ENS broker.
     */
    public static final String ACCESS_TOKEN = PREFIX + "accessToken";
    /**
     * The name of the configuration parameter indicating the host name/IP address of the machine the ENS broker is deployed on.
     */
    public static final String BROKER_HOST = PREFIX + "broker.host";
    /**
     * The name of the configuration parameter indicating the TCP listening port of the ENS broker.
     */
    public static final String BROKER_PORT = PREFIX + "broker.port";
    /**
     * The name of the configuration parameter indicating the name of the broker's virtual host.
     */
    public static final String VIRTUAL_HOST = PREFIX + "broker.vhost";
    /**
     * The name of the configuration parameter indicating the HTTP listening port of the Access Request Broker.
     */
    public static final String MGMT_PORT = PREFIX + "mgmt.port";
    /**
     * The name of the configuration parameter indicating the name of the virtual host resource
     * to be used by the client (i.e. either an AMQP queue or exchange).
     */
    public static final String DESTINATION_NAME = PREFIX + "destinationName";
    /**
     * The name of the configuration parameter that states whether the connection should rely on
     * TLS or not.
     */
    public static final String TLS_ENABLED = PREFIX + "tls";
    /**
     * The name of the configuration parameter indicating the session expiration time.
     */
    public static final String SESSION_EXPIRATION = PREFIX + "session.expiration";
    /**
     * The name of the configuration parameter indicating the session token.
     */
    public static final String SESSION_TOKEN = PREFIX + "session.token";
    static final int NUMBER_OF_MANDATORY_PROPERTIES = 4;
    
    /*
     * an interface cannot define a Builder because we cannot emulate the behavior of a constructor
     * (in the Builder pattern all methods return the Builder instance itself) so we cannot enforce
     * the definition of the mandatory fields in a polite way (i.e. without throwing an
     * IllegalStateException)
     */
    
    /**
     * The default value of the configuration parameter {@link #BROKER_HOST}.
     */
    public static final String DEFAULT_BROKER_HOST = "localhost";
    /**
     * The default value of the configuration parameter {@link #BROKER_PORT}.
     */
    public static final int DEFAULT_BROKER_PORT = 5672;
    /**
     * The default value of the configuration parameter {@link #MGMT_PORT}.
     */
    public static final int DEFAULT_MGMT_PORT = 15672;
    /**
     * The default value of the configuration parameter {@link #VIRTUAL_HOST}.
     */
    public static final String DEFAULT_VIRTUAL_HOST = "/";
    /**
     * The default value of the configuration parameter {@link #SESSION_EXPIRATION}.
     */
    public static final Date DEFAULT_SESSION_EXPIRATION = null;
    /**
     * The default value of the configuration parameter {@link #TLS_ENABLED}.
     */
    public static final boolean DEFAULT_TLS_FLAG = false;
    
    /**
     * Creates a new <code>ENSBrokerConnectionParameters</code> object.
     * 
     * @param subjectID the identifier of the ENS broker user.
     * @param accessToken the access token to be used when connecting to the ENS broker.
     * @param destinationName the name of the virtual host resource
     * to be used by the client (i.e. either an AMQP queue or exchange).
     * @param sessionToken the session token.
     * @return a new <code>ENSBrokerConnectionParameters</code>.
     * @throws IllegalArgumentException if at least one parameter is <code>null</code> or
     * is an empty string.
     */
    public ENSBrokerConnectionParameters create (String subjectID, String accessToken,
            String destinationName, String sessionToken) throws IllegalArgumentException;
    
    /**
     * Creates a new <code>ENSBrokerConnectionParameters</code> object.
     * 
     * @param subjectID the identifier of the ENS broker user.
     * @param accessToken the access token to be used when connecting to the ENS broker.
     * @param brokerHost the host name/IP address of the machine the ENS broker is deployed on.
     * @param brokerPort the TCP listening port of the ENS broker.
     * @param virtualHost the name of the broker's virtual host.
     * @param destinationName the name of the virtual host resource
     * to be used by the client (i.e. either an AMQP queue or exchange).
     * @param tlsEnabled <code>true</code> if the communication should flow through a TLS-secured channel, <code>false</code> otherwise.
     * @param sessionExpiration the session expiration time.
     * @param sessionToken the session token.
     * @return a new <code>ENSBrokerConnectionParameters</code>.
     * @throws IllegalArgumentException if one of the following condition is satisfied:
     * <ul><li>at least one parameter is <code>null</code> or is an empty string</li>
     * <li><code>brokerPort</code> is not a valid TCP port number</li></ul> 
     */
    public ENSBrokerConnectionParameters create (String subjectID, String accessToken, String brokerHost,
            int brokerPort, String virtualHost, String destinationName, boolean tlsEnabled,
            Date sessionExpiration, String sessionToken) throws IllegalArgumentException;
    /**
     * Creates a new <code>ENSBrokerConnectionParameters</code> object.
     * @param subjectID the identifier of the ENS broker user.
     * @param accessToken the access token to be used when connecting to the ENS broker.
     * @param brokerHost the host name/IP address of the machine the ENS broker is deployed on.
     * @param brokerPort the TCP listening port of the ENS broker.
     * @param mgmtPort the HTTP listening port of the ENS broker.
     * @param virtualHost the name of the broker's virtual host.
     * @param destinationName the name of the virtual host resource
     * to be used by the client (i.e. either an AMQP queue or exchange).
     * @param tlsEnabled <code>true</code> if the communication should flow through a TLS-secured channel, <code>false</code> otherwise.
     * @param sessionExpiration the session expiration time.
     * @param sessionToken the session token.
     * @return a new <code>ENSBrokerConnectionParameters</code>.
     * @throws IllegalArgumentException IllegalArgumentException if one of the following condition is satisfied:
     * <ul><li>at least one parameter is <code>null</code> or is an empty string</li>
     * <li><code>brokerPort</code> is not a valid TCP port number</li></ul> 
     * <li><code>mgmtPort</code> is not a valid TCP port number</li></ul>
     */
    public ENSBrokerConnectionParameters create (String subjectID, String accessToken, String brokerHost,
            int brokerPort, int mgmtPort, String virtualHost, String destinationName, boolean tlsEnabled,
            Date sessionExpiration, String sessionToken) throws IllegalArgumentException;
}
